package com.depth.viewer.manager
{
	import com.depth.viewer.container.IWidgetContainer;
	import com.depth.viewer.container.definition.IWidgetContainerDefinition;
	import com.depth.viewer.events.AppEvent;
	import com.depth.viewer.facade.IocAppFacade;
	import com.depth.viewer.request.ConnectionPoolUtil;
	import com.depth.viewer.utils.Util;
	import com.depth.viewer.widget.IBaseWidget;
	import com.depth.viewer.widget.definition.IBaseWidgetDefinition;
	import com.depth.viewer.widget.definition.IWidgetDefinition;
	
	import flash.events.EventDispatcher;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.utils.Dictionary;
	import flash.utils.setTimeout;
	
	import org.springextensions.actionscript.context.IConfigurableApplicationContext;
	
	public class ViewerSystemManager extends EventDispatcher implements IViewerSystemManager
	{
		public static const NAME:String = "ViewerSystemManager";
		
		private var _widgetManager:IWidgetManager;
		private var _facade:IocAppFacade = IocAppFacade.getInstance();
		private var _mainContainer:IWidgetContainer;
		
		private var _configs:Array;
		
		private static var instance:ViewerSystemManager;
		public function ViewerSystemManager()
		{
			addEventListener(AppEvent.CONFIG_LOADED,configLoadedHandler);
		}
		private function configLoadedHandler(e:AppEvent):void{
			init();
		}
		public static function  getInstance():ViewerSystemManager
		{
			if(instance == null){
				instance = new ViewerSystemManager();
			}
			return instance;
		}
		public function get widgetManager():IWidgetManager{
			//var s:Object = _facade.container.getObjectsOfType(IWidgetManager);
			var widgetNames:Array = _facade.container.getObjectNamesForType(IWidgetManager);
			this._widgetManager = _facade.container.getObject(widgetNames[0]);
			if(!_widgetManager){
				throw new Error("框架正在启动，请稍候............！");
			}
			return this._widgetManager;
		}
		public function getFacade():IocAppFacade{
			return this._facade;
		}
		public function start(mainContainer:IWidgetContainer,configs:Array = null):void
		{
			this._mainContainer = mainContainer;
			this._configs = configs;
			
			_facade.initializeIocContainer(configs);
		}
		
		public function restart():void{
			stop();
			start(_mainContainer,_configs);
		}
		
		public function stop():void
		{
			unLoadWidgets();
			unLoadWidgetContainers();
			
			unRegisterWidgetDefinitions();
			unRegisterWidgetContainerDefinitions();
			
			IocAppFacade.reset();
			_facade = IocAppFacade.getInstance();
		}
		
		public function exit():void{
			navigateToURL(new URLRequest('javascript:window.opener=null;window.close()'),'_self');
		}
		
		private function unRegisterWidgetContainerDefinitions():void{
			var widgetContainerRegistry:IWidgetContainerRegistry = widgetManager.getRegistry();
			var widgetContainerDefs:Array = [];
			Util.connect(widgetContainerDefs,widgetContainerRegistry.getRegistedWidgetDefinitions());
			for each(var widgetContainerDef:IWidgetContainerDefinition in widgetContainerDefs){
				widgetContainerRegistry.unRegisterWidgetDefinition(widgetContainerDef.id);
			}
		}
		
		private function unRegisterWidgetDefinitions():void{
			var widgetRegistry:IWidgetRegistry = widgetManager.getRegistry().getRegistry();
			var widgetDefs:Array = [];
			Util.connect(widgetDefs,widgetRegistry.getRegistedWidgetDefinitions());
			for each(var widgetDef:IWidgetDefinition in widgetDefs){
				widgetRegistry.unRegisterWidgetDefinition(widgetDef.id);
			}
		}
		
		private function unLoadWidgetContainers():void{
			var widgetContainers:Array =  widgetManager.getRegistry().getRegistedWidgets();
			for each(var widgetContainer:IBaseWidget in widgetContainers){
				IocAppFacade.sendNotification(IocAppFacade.UNLOAD_WIDGET,widgetContainer.widgetId);
			}
		}
		
		private function unLoadWidgets():void{
			var widgets:Array =  widgetManager.getRegistry().getRegistry().getRegistedWidgets();
			for each(var widget:IBaseWidget in widgets){
				IocAppFacade.sendNotification(IocAppFacade.UNLOAD_WIDGET,widget.widgetId);
			}
		}
		
		protected function init():void{
			initialize();
			registerWidgetContainerDefinition();
			registerWidgetDefinition();
			initLoadWidgetContainers();
			initLoadWidgets();
			initConnectionPool();
		}
		private function initConnectionPool ():void{
			trace("-----------------初始化连接池");
			ConnectionPoolUtil.instance;
		}
		
		private function initLoadWidgetContainers():void{
			if(widgetManager){
				var registry:IWidgetContainerRegistry = widgetManager.getRegistry();
				var defs:Array = registry.getRegistedWidgetDefinitions();
				for each(var def:IWidgetContainerDefinition in defs){
					IocAppFacade.sendNotification(IocAppFacade.LOAD_WIDGET,def.id);//widgetManager.loadWidget(def.id);
				}
			}
		}
		private function initLoadWidgets():void{
			if(widgetManager){
				var registry:IWidgetRegistry = widgetManager.getRegistry().getRegistry();
				var defs:Array = registry.getRegistedWidgetDefinitions();
				
				var tempDefs:Array = [];
				Util.connect(tempDefs,defs);
				
				var priorityLoads:Dictionary = new Dictionary();
				for each(var def:IBaseWidgetDefinition in tempDefs){
					if(!def.container){
						Util.removeItem(defs,def);
						continue;
					}
					if(def.autoRun && def.priorityLevel != -1 && def.autoLoadDelay == 0){
						var pdefs:Array = priorityLoads[def.priorityLevel];
						if(!pdefs){
							pdefs = [];
							priorityLoads[def.priorityLevel] = pdefs;
						}
						pdefs.push(def);
					} 
					if(def.autoRun && def.autoLoadDelay > 0){
						setTimeout(function(widgetId):void{
							IocAppFacade.sendNotification(IocAppFacade.LOAD_WIDGET,widgetId);//widgetManager.loadWidget(widgetId);
						},def.autoLoadDelay,def.id);
						Util.removeItem(defs,def);
					}
				}
				var levels:Array = Util.getObjectAttributes(priorityLoads);
				levels.sort();
				
				for each(var level:int in levels){
					var pdefs:Array = priorityLoads[level] as Array;
					for each(var def:IBaseWidgetDefinition in pdefs){
						IocAppFacade.sendNotification(IocAppFacade.LOAD_WIDGET,def.id);//widgetManager.loadWidget(def.id);
						Util.removeItem(defs,def);
					}
				}
				
				for each(var def:IBaseWidgetDefinition in defs){
					if(def.autoRun){
						IocAppFacade.sendNotification(IocAppFacade.LOAD_WIDGET,def.id);//widgetManager.loadWidget(def.id);
					}
				}/*
				for each(var def:IBaseWidgetDefinition in defs){
				if(def.autoRun && !def.prioredRun){
				widgetManager.loadWidget(def.id);
				}
				}*/
			}
		}
		/*private function loadNextWidgetContainer(widgetContainers:Array):void{
		if(widgetManager){
		var def:IWidgetContainerDefinition = widgetContainers.shift();
		widgetManager.loadWidget(def);
		}
		}*/
		private function registerWidgetContainerDefinition():void{
			if(widgetManager){
				var container:IConfigurableApplicationContext = getFacade().container;
				var registry:IWidgetContainerRegistry = widgetManager.getRegistry();
				var defNames:Array = container.getObjectNamesForType(IWidgetContainerDefinition);
				for each(var defName:String in defNames){
					var def:IWidgetContainerDefinition = container.getObject(defName);
					registry.registerWidgetDefinition(def);
				}
			}
		}
		private function registerWidgetDefinition():void{
			if(widgetManager){
				/*var container:IConfigurableApplicationContext = getFacade().container;
				var registry:IWidgetRegistry = widgetManager.getRegistry().getRegistry();
				var cdefNames:Array = container.getObjectNamesForType(IWidgetContainerDefinition);
				for each(var cdefName:String in cdefNames){
				var cdef:IWidgetContainerDefinition = container.getObject(cdefName);
				var wdefs:ArrayCollection = cdef.widgetDefinitions;
				for each(var wdef:IWidgetDefinition in wdefs){
				registry.registerWidgetDefinition(wdef);
				trace("己注册widget:      -------------------  " + wdef.id);
				}
				}	*/
				
				var registry:IWidgetRegistry = widgetManager.getRegistry().getRegistry();
				var container:IConfigurableApplicationContext = getFacade().container;
				var defNames:Array = container.getObjectNamesForType(IBaseWidgetDefinition);
				for each(var defName:String in defNames){
					var def:IWidgetDefinition = container.getObject(defName);
					registry.registerWidgetDefinition(def);
				}
			}
		}
		private function initialize():void{
			widgetManager.setViewComponent(_mainContainer);
			_facade.registerMediator(_widgetManager);
		}
	}
}